package com.inspur.edp.formserver.vmmanager.util;

import com.inspur.edp.bef.bizentity.pushchangesetargs.ElementChangeDetail;
import com.inspur.edp.bef.bizentity.util.StringUtil;
import com.inspur.edp.cef.designtime.api.IGspCommonField;
import com.inspur.edp.cef.designtime.api.json.CefNames;
import com.inspur.edp.das.commonmodel.json.CommonModelNames;
import com.inspur.edp.formserver.viewmodel.GspViewModelElement;
import com.inspur.edp.formserver.viewmodel.GspViewObject;
import com.inspur.edp.formserver.viewmodel.exception.ViewModelException;
import com.inspur.edp.formserver.vmmanager.exception.VoManagerErrorCodes;

import java.util.Iterator;
import java.util.Map;


public class PushElementChangeSet extends PushObjectChangeSet {

    public PushElementChangeSet() {
    }

    public GspViewModelElement getElementById(GspViewObject object, String refElementId) {
        for (IGspCommonField ele : object.getContainElements()) {
            if (compareRefElementId((GspViewModelElement) ele, refElementId)) {
                return ((GspViewModelElement) ele);
            }
        }
        return null;
    }

    public void addElement(GspViewObject object, GspViewModelElement element) {
        if (object != null && element != null
                && object.getContainElements().getByLabelId(element.getLabelID()) == null) {
            object.getContainElements().add(element);
        }
    }

    public void modifyElement(GspViewModelElement destElement, GspViewModelElement refElement, ElementChangeDetail changeDetail) {
        Map<String, Object> changeInfo = changeDetail.getChangeInfo();
        if (destElement == null) {
            return;
        }
        changeInfo.forEach((key, val) -> {
            modifyElementPropertyValue(key, val, destElement, refElement);
        });
    }

    private void modifyElementPropertyValue(String propertyName, Object propertyValue, GspViewModelElement destElement, GspViewModelElement refElement) {
        switch (propertyName) {
            case CommonModelNames.Code:
            case CommonModelNames.LabelID:
                destElement.setCode((String) propertyValue);
                destElement.setLabelID((String) propertyValue);
                break;
            case CefNames.MDataType:
                setMDataType(destElement, refElement);
                break;
            case CefNames.Length:
                destElement.setLength((Integer) propertyValue);
                break;
            case CefNames.Precision:
                destElement.setPrecision((Integer) propertyValue);
                break;
            case CefNames.ObjectType:
                setObjectType(destElement, refElement);
                break;
            case CefNames.IsMultiLanguage:
                destElement.setIsMultiLanguage((Boolean) propertyValue);
                break;
            case CefNames.IsRequire:
                destElement.setIsRequire((Boolean) propertyValue);
                break;
            case CefNames.EnableRtrim:
                destElement.setEnableRtrim((Boolean) propertyValue);
                break;
            case CefNames.IsUdt:
                setUdt(destElement, refElement);
                break;
            default:
                throw new ViewModelException(VoManagerErrorCodes.GSP_VIEWOBJECT_MANAGER_0072, null, propertyName, destElement.getCode(), destElement.getName());
        }

    }

    private void setObjectType(GspViewModelElement destElement, GspViewModelElement refElement) {
        destElement.setObjectType(refElement.getObjectType());
        destElement.setChildAssociations(refElement.getChildAssociations());
        destElement.setContainEnumValues(refElement.getContainEnumValues());
        destElement.setDynamicPropSetInfo(refElement.getDynamicPropSetInfo());
    }

    private void setMDataType(GspViewModelElement destElement, GspViewModelElement refElement) {
        if (refElement == null) {
            return;
        }
        if (destElement.getDefaultValue() != null && destElement.getDefaultValue().length() > 0) {
            destElement.setDefaultValue("");
        }
        // 数据类型会同步修改长度精度
        destElement.setMDataType(refElement.getMDataType());
        destElement.setLength(refElement.getLength());
        destElement.setPrecision(refElement.getPrecision());
        //数据类型从udt类型修改回普通类型
        setUdt(destElement, refElement);
    }

    private void setUdt(GspViewModelElement destElement, GspViewModelElement refElement) {
        if (refElement == null)
            return;
        if (destElement.getDefaultValue() != null && destElement.getDefaultValue().length() > 0) {
            destElement.setDefaultValue("");
        }
        destElement.setIsUdt(refElement.getIsUdt());
        destElement.setUdtID(refElement.getUdtID());
        destElement.setUdtName(refElement.getUdtName());
        destElement.setMapping(refElement.getMapping());
    }

    public void deleteElement(GspViewObject orgObject, String refElementId) {
        if (orgObject == null || StringUtil.checkNull(refElementId)) {
            return;
        }
        Iterator<IGspCommonField> iterator = orgObject.getContainElements().iterator();
        while (iterator.hasNext()) {
            if (compareRefElementId((GspViewModelElement) iterator.next(), refElementId)) {
                iterator.remove();
            }
        }
    }

    private boolean compareRefElementId(GspViewModelElement vmElement, String refId) {
        if (vmElement.getMapping() != null &&
                !StringUtil.checkNull(vmElement.getMapping().getTargetElementId()) &&
                vmElement.getMapping().getTargetElementId().equals(refId)) {
            return true;
        }
        return false;
    }
}
